-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Properly constrain the basic_json conversion operator #2825
Conversation
I'm not sure what standards you support. If some of the type traits (e.g. I'm now going to close http://llvm.org/PR48507 because it's not a libc++ bug. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just two comments to compare with my PR. The appearance of a new PR made me update mine. 😉
template<template<class...> class Op, class... Args> | ||
struct is_detected_lazy : is_detected<Op, Args...> { }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, That's done way better than in my PR. I like the idea of making the number of additional instantiations as small as possible, and this allows to eliminate unnecessary instantiations. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just two comments to compare with my PR. The appearance of a new PR made me update mine. 😉
Sorry, I didn't realize there was already a PR for this.
include/nlohmann/json.hpp
Outdated
std::conjunction< | ||
std::negation<std::is_pointer<ValueType>>, | ||
std::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>, | ||
std::negation<std::is_same<ValueType, typename string_t::value_type>>, | ||
std::negation<detail::is_basic_json<ValueType>>, | ||
std::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>, | ||
|
||
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914)) | ||
&& !std::is_same<ValueType, typename std::string_view>::value | ||
std::negation<std::is_same<ValueType, std::string_view>>, | ||
#endif | ||
&& detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value | ||
, int >::type = 0 > | ||
detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType> | ||
>::value, int >::type = 0 > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, there is no much sense to use templated/typed/parametrized logic operations for all operands. For the same reason as above. Of course, it can backfire in the future, but it wouldn't hurt too much since these operands can be replaced pretty quickly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could technically do something like:
std::conjunction<
std::bool_constant<
!std::is_pointer<ValueType>::value &&
!std::is_same<ValueType, detail::json_ref<basic_json>>::value &&
!std::is_same<ValueType, typename string_t::value_type>::value &&
!detail::is_basic_json<ValueType>::value &&
!std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value &&
// ...
>,
detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
>
But I don't think it provides a big benefit, and it's less consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, actually, it's
json/include/nlohmann/json.hpp
Lines 3345 to 3357 in ae9cfb1
detail::conjunction < | |
std::integral_constant < bool, | |
!std::is_pointer<ValueType>::value&& | |
!std::is_same<ValueType, detail::json_ref<basic_json>>::value&& | |
!std::is_same<ValueType, typename string_t::value_type>::value&& | |
!detail::is_basic_json<ValueType>::value | |
&& !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value | |
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914)) | |
&& !std::is_same<ValueType, typename std::string_view>::value | |
#endif | |
>, | |
detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType >>::value | |
, int >::type = 0 > |
You are right about consistency for sure. Does it give a big benefit - I don't know, I'm just hoping that it helps. But looking more at this library, probably a few more instantiations wouldn't be noticeable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please update this branch to the latest develop branch?
Rebased onto |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test for the amalgamation (https://github.com/nlohmann/json/runs/3104916288?check_suite_focus=true) failed. Can you please run make amalgamate
- this should re-indent and regenerate the single header.
It looks like there's nothing to be done on my system for
|
That is strange. Can you try to delete file |
Now that seems to make a difference, thanks. |
Thank you for your patience! |
The remaining issue in the CI has been fixed in the develop branch, so technically this PR is ready to be merged. As I am no expert in template magic, I do no really understand the fix. @gregmarr @alexezeder can either of you have a quick look whether the changes are OK to you? |
I cannot call myself an expert in template magic either, but since I understand what causes the errors here - the changes are OK to me. I've already reviewed this PR, and I agree with the @ldionne that it's not worth changing logic operations for all operands for consistency. Also, as @ldionne mentioned, it doesn't provide a big benefit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
Thanks! |
Fixes #2491
This was reported as a libc++ bug in http://llvm.org/PR48507, but it's a bug in this library, not in libc++. See Richard Smith's explanation in http://llvm.org/PR48507.